// 类方式
class Promise {

    constructor(executor) {
        this.PromiseState = 'pending'
        this.PromiseResult = undefined
        this.callbacks = []

        //成功回调
        const resolved = data => {
            // 保证状态只能改变一次
            if (this.PromiseState !== 'pending') {
                return
            }
            this.PromiseState = 'fulfilled'
            this.PromiseResult = data
            // 异步任务时保证后续执行
            this.callbacks.forEach(item => {
                item.onResolved(this.PromiseResult)
            })
        }
        // 失败回调
        const rejected = data => {
            // 保证状态只能改变一次
            if (this.PromiseState !== 'pending') {
                return
            }
            this.PromiseState = 'rejected'
            this.PromiseResult = data
            // 异步任务时保证后续执行
            this.callbacks.forEach(item => {
                item.onRejected(this.PromiseResult)
            })
        }
        try {
            // 同步调用 执行器函数
            executor(resolved, rejected)
        } catch (e) {
            rejected(e)
        }
    }

    then(onResolved, onRejected) {
        return new Promise((resolve, reject) => {
            //封装回调
            const callback = (type) => {
                try {
                    // 注意函数内部this指向，使用箭头函数改变指向
                    let result = type(this.PromiseResult);
                    if (result instanceof Promise) {
                        result.then(value => {
                            resolve(value)
                        }, reason => {
                            reject(reason)
                        })
                    } else {
                        // 成功回调
                        resolve(result)
                    }
                } catch (e) {
                    reject(e)
                }
            }
            // 添加默认成功回调，保证空参then()后续能继续执行
            if (typeof onResolved !== 'function') {
                onResolved = value => value
            }
            // 添加默认失败回调，保证异常穿透
            if (typeof onRejected !== 'function') {
                onRejected = reason => {
                    throw reason
                }
            }

            // 成功回调
            if (this.PromiseState === 'fulfilled') {
                setTimeout(() => {
                    callback(onResolved)
                })
            }
            // 失败回调
            if (this.PromiseState === 'rejected') {
                setTimeout(() => {
                    callback(onRejected)
                })
            }
            // 发生异步任务 等待执行
            // 将回调函数保存到callbacks中，方便后续调用
            if (this.PromiseState === 'pending') {
                this.callbacks.push({
                    onResolved: () => {
                        // 执行成功的回调函数
                        callback(onResolved)
                    },
                    onRejected: () => {
                        callback(onRejected)
                    }
                })
            }
        })

    }

    catch(onRejected) {
        return this.then(undefined, onRejected)
    }

    static resolve(value) {
        return new Promise((resolve, reject) => {
                if (value instanceof Promise) {
                    value.then(v => {
                        resolve(v)
                    }, r => {
                        reject(r)
                    })
                } else {
                    resolve(value)
                }
            }
        )
    }

    static reject(reason) {
        return new Promise((resolve, reject) => {
            reject(reason)
        })
    }

    static all(promises) {
        return new Promise((resolve, reject) => {
            let count = 0
            let values = []
            for (let i = 0; i < promises.length; i++) {
                promises[i].then(value => {
                    values[i] = value
                    // 全部成功 才能执行resolve，将状态该置为成功
                    if (++count === promises.length) {
                        resolve(values)
                    }
                }).catch(reason => {
                    reject(reason)
                })
            }
        })
    }

    static race(promises) {
        return new Promise((resolve, reject) => {
            for (let i = 0; i < promises.length; i++) {
                promises[i].then(value => {
                    resolve(value)
                }, reason => {
                    reject(reason)
                })
            }
        })
    }
}

/*
// 函数方式
function Promise(executor) {
    this.PromiseState = 'pending'
    this.PromiseResult = undefined
    this.callbacks = []

    //成功回调
    const resolved = data => {
        // 保证状态只能改变一次
        if (this.PromiseState !== 'pending') {
            return
        }
        this.PromiseState = 'fulfilled'
        this.PromiseResult = data
        // 异步任务时保证后续执行
        this.callbacks.forEach(item => {
            item.onResolved(this.PromiseResult)
        })
    }
    // 失败回调
    const rejected = data => {
        // 保证状态只能改变一次
        if (this.PromiseState !== 'pending') {
            return
        }
        this.PromiseState = 'rejected'
        this.PromiseResult = data
        // 异步任务时保证后续执行
        this.callbacks.forEach(item => {
            item.onRejected(this.PromiseResult)
        })
    }
    try {
        // 同步调用 执行器函数
        executor(resolved, rejected)
    } catch (e) {
        rejected(e)
    }
}

Promise.prototype.then = function (onResolved, onRejected) {
    return new Promise((resolve, reject) => {
        //封装回调
        const callback = (type) => {
            try {
                // 注意函数内部this指向，使用箭头函数改变指向
                let result = type(this.PromiseResult);
                if (result instanceof Promise) {
                    result.then(value => {
                        resolve(value)
                    }, reason => {
                        reject(reason)
                    })
                } else {
                    // 成功回调
                    resolve(result)
                }
            } catch (e) {
                reject(e)
            }
        }
        // 添加默认成功回调，保证空参then()后续能继续执行
        if (typeof onResolved !== 'function') {
            onResolved = value => value
        }
        // 添加默认失败回调，保证异常穿透
        if (typeof onRejected !== 'function') {
            onRejected = reason => {
                throw reason
            }
        }

        // 成功回调
        if (this.PromiseState === 'fulfilled') {
            setTimeout(() => {
                callback(onResolved)
            })
        }
        // 失败回调
        if (this.PromiseState === 'rejected') {
            setTimeout(() => {
                callback(onRejected)
            })
        }
        // 发生异步任务 等待执行
        // 将回调函数保存到callbacks中，方便后续调用
        if (this.PromiseState === 'pending') {
            this.callbacks.push({
                onResolved: () => {
                    // 执行成功的回调函数
                    callback(onResolved)
                },
                onRejected: () => {
                    callback(onRejected)
                }
            })
        }
    })

}

Promise.prototype.catch = function (onRejected) {
    return this.then(undefined, onRejected)
}

Promise.resolve = function (value) {
    return new Promise((resolve, reject) => {
            if (value instanceof Promise) {
                value.then(v => {
                    resolve(v)
                }, r => {
                    reject(r)
                })
            } else {
                resolve(value)
            }
        }
    )
}
// reject方法，返回对象永远为失败的对象
Promise.reject = function (reason) {
    return new Promise((resolve, reject) => {
        reject(reason)
    })
}

Promise.all = function (promises) {
    return new Promise((resolve, reject) => {
        let count = 0
        let values = []
        for (let i = 0; i < promises.length; i++) {
            promises[i].then(value => {
                values[i] = value
                // 全部成功 才能执行resolve，将状态该置为成功
                if (++count === promises.length) {
                    resolve(values)
                }
            }).catch(reason => {
                reject(reason)
            })
        }
    })
}

// race 方法 谁先执行 就返回谁的结果
Promise.race = function (promises) {
    return new Promise((resolve, reject) => {
        for (let i = 0; i < promises.length; i++) {
            promises[i].then(value => {
                resolve(value)
            }, reason => {
                reject(reason)
            })
        }
    })
}*/